let

fs = require('fs')
exec = require('child_process').exec

gulp = require('gulp')
concat = require('gulp-concat')
uglify = require('gulp-uglify')
cssmin = require('gulp-clean-css')

md5 = require('md5-file')
args = require('yargs').argv
web = require('browser-sync').create()

// gulp 参数
style = args.style || 'default' // 使用哪个样式文件 默认 default.sass

now = () => {
  let d = new Date()
  return `[${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}]`
}

/**
 * 对 lib/*.js 以及 tag/*.js 创建
 */
createRVM = (cb) => {
  let
  libs = {}, tags = {}, styles = {},
  promiseStyle, promiseLib, promiseTag;

  // style
  promiseStyle = new Promise((resolve, reject) => {
    fs.readdir('app/dist/style', (err, files) => {
      if(err) { return reject(err); }
      // 循环 style 文件写入md5后缀
      files.forEach(f => {
        let file = `app/dist/style/${f}`, v
        if(!fs.lstatSync(file).isFile()) return
        v = md5.sync(file)
        styles[f.replace('.css', '')] = `dist/style/${f}?${v}`
      })
      resolve()
    })
  })

  // lib
  promiseLib = new Promise((resolve, reject) => {
    fs.readdir('app/dist/lib', (err, files) => {
      if(err) { return reject(err); }
      // 循环 lib 文件写入md5后缀
      files.forEach(f => {
        let file = `app/dist/lib/${f}`, v
        if(!fs.lstatSync(file).isFile()) return
        v = md5.sync(file)
        libs[f.replace('.js', '')] = `dist/lib/${f}?${v}`
      })
      resolve()
    })
  })

  // tag
  promiseTag = new Promise((resolve, reject) => {
    fs.readdir('app/dist/tag', (err, files) => {
      if(err) { return reject(err); }
      // 循环tag文件写入md5后缀
      files.forEach(f => {
        let file = `app/dist/tag/${f}`, v
        if(!fs.lstatSync(file).isFile()) return
        v = md5.sync(file)
        tags[f.replace('.js', '')] = `dist/tag/${f}?${v}`
      })
      resolve()
    })
  })

  Promise.all([promiseStyle, promiseLib, promiseTag])
  .then(() => {
    let content = JSON.stringify({tags, libs, styles});
    fs.writeFile('app/dist/rvm.json', content, (err) => {
      if(err) reject(err)
      else{
        console.log(now(), `dist / rvm.json ☕ `)
        cb && cb()
      }
    })
  }).catch(err => {
    console.log(err)
  })
}

/**
 * 压缩 main.js
 */
gulp.task('dist:main', () => {
  return gulp.src('src/main.js')
  .pipe(uglify())
  .pipe(gulp.dest('app/dist'))
})

/**
 * 合并压缩 core.js
 */
gulp.task('dist:core', () => {
  return gulp.src([
    'src/core/pip.js',
    'src/core/riot.js'
  ])
  .pipe(concat('app/dist/core.js'))
  .pipe(uglify())
  .pipe(gulp.dest('.'))
})

/**
 * 压缩 lib/*.js
 */
gulp.task('dist:lib', () => {
  return gulp.src('src/lib/*.js')
  .pipe(uglify())
  .pipe(gulp.dest('app/dist/lib'))
})

/**
 * 编译并压缩riot tag
 */
gulp.task('dist:tag', () => {

  let

  promiseMerge = new Promise((resolve, reject) => {
    exec(`riot src/tag/merge app/dist/tag/_merge.js`, err => {
      if(err) reject(err)
      else{
        console.log(now(), `merge / * 编译&合并 ☕ `)
        resolve()
      }
    })
  }),

  promisePage = new Promise((resolve, reject) => {
    exec(`riot src/tag/page app/dist/tag`, err => {
      if(err) reject(err)
      else{
        console.log(now(), `page / * 编译 ☕ `)
        resolve()
      }
    })
  });

  return Promise.all([promiseMerge, promisePage])
  .then(() => {
    gulp.src('app/dist/tag/*.js')
    .pipe(uglify())
    .pipe(gulp.dest('app/dist/tag'))
    console.log(now(), `dist / tag / * 压缩 ☕ `)
  }).catch(err => {
    console.log(err)
  })

})

/**
 * dist style
 */
gulp.task('dist:style', () => {
  exec(`node-sass src/style/${style}.sass app/dist/style/${style}.css`, err => {
    if(err) throw err
    gulp.src(`app/dist/style/${style}.css`)
    .pipe(cssmin())
    .pipe(gulp.dest(`app/dist/style`))
    console.log(now(), `style / ${style}.sass ☕ `)
  })
})

/**
 * dist 合并
 */
gulp.task('dist', [
  'dist:core', 'dist:main', 'dist:lib', 'dist:tag', 'dist:style'
], () => {
  createRVM(() => {
    let rvm, html
    // 创建 app html
    rvm = JSON.parse(fs.readFileSync('app/dist/rvm.json', 'utf8'))
    html = fs.readFileSync('src/_index.html', 'utf8')
    html = html.replace('{style}', rvm.styles[style])
    html = html.replace('{core}', md5.sync('app/dist/core.js'))
    html = html.replace('{main}', md5.sync('app/dist/main.js'))
    fs.writeFile('app/index.html', html, err => {
      if(err) throw err
      console.log(now(), `dist / index.html ☕ `)
    })
  })
})

/**
 * 开发web服务器启动
 */
gulp.task('dev:web', () => {

  web.init({
    server: {
      baseDir: 'app', index: 'index.html'
    },
    notify: false
  })

  gulp.watch([
    'app/dist/lib/*', 'app/dist/style/*',
    'app/dist/tag/*', 'app/dist/*.js'
  ]).on('change', web.reload);

})

/**
 * 开发样式(sass)也可以自己改写成其他语言
 */
gulp.task('dev:style', () => {
  gulp.watch(`src/style/**/*`, ['dist:style'])
})

/**
 * 开发 riot tag
 */
gulp.task('dev:tag', () => {
  gulp.watch('src/tag/page/*.tag')
  .on('change', evt => {
    if(evt.type !== 'deleted'){
      exec(`riot ${evt.path} app/dist/tag`, err => {
        if(err) throw err
        console.log(now(), `page / ${evt.path.split('/').pop()} ☕ `)
        // 不是改变源文件的需要写入rvm
        if(evt.type !== 'changed'){
          createRVM()
        }
      })
    }
  })
  gulp.watch('src/tag/merge/*.tag')
  .on('change', evt => {
    exec(`riot src/tag/merge app/dist/tag/_merge.js`, err => {
      if(err) throw err
      console.log(now(), `merge / * 编译&合并 ☕ `)
    })
  })
})

/**
 * 开发 core.js
 */
gulp.task('dev:core', () => {
  gulp.watch('src/core/*.js', ['dist:core'])
})

/**
 * 开发 main.js
 */
gulp.task('dev:main', () => {
  gulp.watch('src/main.js', ['dist:main'])
})

/**
 * 开发 lib/*.js
 */
gulp.task('dev:lib', () => {
  gulp.watch('src/lib/*.js', ['dist:lib'])
})

/**
 * 启动开发模式
 */
gulp.task('dev', ['dist'], () => {
  gulp.start([
    'dev:core', 'dev:style', 'dev:tag',
    'dev:main', 'dev:lib', 'dev:web'
  ])
})
